// 科里化：利用闭包的机制接收一部分参数，返回一个函数接收剩余参数，接收足够参数后，执行原函数
function sum(a,b,c) {
    return a + b + c
}


// 柯里化第一种

function curry(fun,...args) {
  return function (...restArgs) {
    let allArgs = [...args,...restArgs];
    // 说明已经收集完参数了，则执行原函数
    if(allArgs.length >= fun.length) {
      return fun.apply(this,allArgs)
    }else {
      return curry(fun,...allArgs)
    }
  }
}

// 柯里化第二种
function curryPlus(fun) {
    const fnLength = fun.length;
    let args = [];
    function _curry(...innerArgs) {
        args = [...args,...innerArgs];
        if(args.length >= fnLength) {
            return fun.apply(this, args.slice(0, fnLength));
        }else {
            return _curry
        }
    }
    return _curry;
}

const curryFnArg = curry(sum,1,2);
console.log('求和为1：' ,curryFnArg(3)) // 适合第一种写法，可以传一个固定的参数
// const curryFn = curryPlus(sum); // 适合第二种写法，只传一个要科里化的函数
// console.log('求和为2：',curryFn(1,2)(3))